package com.cardrive.util;

import java.util.Vector;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.AsyncTask;
import android.util.Log;

import com.cardrive.listeners.IAnimationEventListener;
import com.cardrive.listeners.IFrameListener;

public class AnimatedSprite extends Sprite {

	private boolean isInfinite, move;
	private Vector<Bitmap> bitmapList = null;
	private int bitmapAssets[] = null;
	private int totalImg, currentFrame, startFrame;
	private int numReps = 1;
	private boolean paused = false;
	private Context context = null;

	private boolean isBitmapMode = false;
	private boolean isBitmapsReady = false;
	private boolean preLoad = false;

	private IFrameListener currentFrameListener = null;

	private String assetSound = null;
	public boolean isSoundLoaded = false;

	private IAnimationEventListener animationListener = null;

	public AnimatedSprite(int x, int y, Context context, int assets[],
			boolean isBitmapMode, boolean preLoad) {
		super(context, assets[0], x, y);
		this.context = context;
		this.bitmapAssets = assets;
		this.currentFrame = 0;
		this.startFrame = 0;
		this.isInfinite = false;
		this.move = false;
		this.totalImg = assets.length;

		this.isBitmapMode = isBitmapMode;
		this.preLoad = preLoad;

		preload();

	}

	private void preload() {
		if (preLoad) {
			BitmapLoader bitmapLoader = new BitmapLoader();

			bitmapLoader.execute();
		}
	}

	public void playAnimation() {
		move = true;
		paused = false;
	}

	/**
	 * Play a quick and complete animation of one repetition of this Animated
	 * Sprite. Execute stopAnimation(), setNumReps(1), playAnimation
	 */
	public void quickPlayAnimation() {
		stopAnimation();
		setNumReps(1);
		playAnimation();
	}

	public void pauseAnimation() {
		move = false;
		paused = true;
	}

	public void stopAnimation() {
		move = false;
		paused = false;
		currentFrame = 0;
		startFrame = 0;
	}

	public void setNumReps(int numReps) {
		this.numReps = numReps;
	}

	public void setSound(String assetSound) {
		this.setAssetSound(assetSound);
		this.isSoundLoaded = true;
	}

	@Override
	public void render(Canvas canvas, Paint paint) {
		super.render(canvas, paint);
		if (numReps > 0 && move) {
			if (move) {
				if (currentFrame == 0) {
					if (isSoundLoaded) {
						// PlaySound.playAssetSound(context, assetSound);
					} else {
					}
				}
				currentFrame++;
				if (currentFrame >= this.totalImg)
					currentFrame = 0;

				// inform to parent class in witch frame is this animation
				if (currentFrameListener != null) {
					currentFrameListener.onCurrentFrame(currentFrame);
				}

				if (move) {
					if (isBitmapMode) {
						if (bitmapList != null && bitmapList.size() > 0
								&& currentFrame < bitmapList.size()
								&& bitmapList.get(currentFrame) != null) {
							this.setImage(bitmapList.get(currentFrame));
						}
					} else {
						if (bitmapAssets != null && bitmapAssets.length > 0
								&& currentFrame < bitmapAssets.length) {
							if (this.getImage() != null)
								this.getImage().recycle();
							Bitmap bmp = Utils.decodeBitmap(
									context.getResources(),
									bitmapAssets[currentFrame]);
							this.setImage(bmp);
						}
					}

				}

				if (!isInfinite) {
					if (currentFrame == startFrame) {
						numReps--;
						stopAnimation();
						if (numReps > 0) {
							playAnimation();
						} else {
							currentFrame = 0;
							Log.d("AnimatedSprite", "Animation finished");
							if (animationListener != null) {
								animationListener.onAnimationFinished();
							}
						}

					}
					// GameEngine.input_bloqued = !stop;
				}
			}
		}

	}

	public void setArrayList(int arrayList[], boolean isBitmapMode,
			boolean preLoad) {
		this.preLoad = preLoad;
		this.bitmapAssets = arrayList;
		this.setImage(Utils.decodeBitmap(context.getResources(), arrayList[0]));
		this.totalImg = arrayList.length;
		if (preLoad) {
			BitmapLoader bitmapLoader = new BitmapLoader();

			bitmapLoader.execute();
		}
		stopAnimation();
	}

	public void unloadResources() {
		if (bitmapList != null) {
			for (int i = 0; i < bitmapList.size(); i++) {
				bitmapList.get(i).recycle();
				bitmapList.set(i, null);
			}
			bitmapList.removeAllElements();
			bitmapList = null;
		}
	}

	public void nextFrame() {
		if (currentFrame < getTotalImg() - 1) {
			currentFrame++;
			setCurrentFrame(currentFrame);
		}
	}

	public void nextFrameCyclic() {
		if (currentFrame < getTotalImg() - 1) {
			currentFrame++;
		} else {
			currentFrame = 0;
		}
		setCurrentFrame(currentFrame);
	}

	private class BitmapLoader extends AsyncTask<Object, Void, Void> {

		@Override
		protected Void doInBackground(Object... params) {

			if (bitmapList != null) {
				bitmapList.removeAllElements();
			}
			Vector<Bitmap> bitmaps = new Vector<Bitmap>();
			for (int i = 0; i < bitmapAssets.length; i++) {
				bitmaps.add(Utils.decodeBitmap(context.getResources(),
						bitmapAssets[i]));
				Log.d("AnimatedSprite", "loading bitmaps");
			}

			bitmapList = bitmaps;

			isBitmapsReady = true;

			return null;
		}

	}

	public boolean isInfinite() {
		return isInfinite;
	}

	public void setInfinite(boolean isInfinite) {
		this.isInfinite = isInfinite;
	}

	public int getTotalImg() {
		return totalImg;
	}

	public void setTotalImg(int totalImg) {
		this.totalImg = totalImg;
	}

	public boolean isMove() {
		return move;
	}

	public void setMove(boolean move) {
		this.move = move;
	}

	public Vector<Bitmap> getBitmapList() {
		return bitmapList;
	}

	public int getNumReps() {
		return numReps;
	}

	public IFrameListener getCurrentFrameListener() {
		return currentFrameListener;
	}

	public void setCurrentFrameListener(IFrameListener currentFrameListener) {
		this.currentFrameListener = currentFrameListener;
	}

	public boolean isPaused() {
		return paused;
	}

	public void setPaused(boolean paused) {
		this.paused = paused;
	}

	public IAnimationEventListener getAnimationListener() {
		return animationListener;
	}

	public void setAnimationListener(IAnimationEventListener animationListener) {
		this.animationListener = animationListener;
	}

	public int getCurrentFrame() {
		return currentFrame;
	}

	public void setCurrentFrame(int currentFrame) {
		this.currentFrame = currentFrame;
		if (!isBitmapMode) {
			if (this.getImage() != null)
				this.getImage().recycle();
			Bitmap bmp = Utils.decodeBitmap(context.getResources(),
					bitmapAssets[currentFrame]);
			bmp.prepareToDraw();
			this.setImage(bmp);
			bmp = null;
		} else {
			this.setImage(bitmapList.get(currentFrame));
		}
	}

	public boolean isBitmapMode() {
		return isBitmapMode;
	}

	public void setBitmapMode(boolean bitmapMode) {
		this.isBitmapMode = bitmapMode;
	}

	public boolean isPreLoad() {
		return preLoad;
	}

	public void setPreLoad(boolean preLoad) {
		this.preLoad = preLoad;
	}

	public boolean isBitmapsReady() {
		return isBitmapsReady;
	}

	public void setBitmapsReady(boolean bitmapsReady) {
		this.isBitmapsReady = bitmapsReady;
	}

	public String getAssetSound() {
		return assetSound;
	}

	public void setAssetSound(String assetSound) {
		this.assetSound = assetSound;
	}

}